import { bar, Effect_tag, EffectCondition, EffectType, group, Sk_minType, SK_type } from "../../../shared/interface";
import { baseBody } from "../body/baseBody";
import app, { xlsxCfgNames } from "../../../app";
import { cfg_effectKey } from "../../../intoSkill/cfg_effect";
import { logger } from "../../server/logger";
import SK_applyEffect from "./SK_applyEffect";
import SK_getTag from "./SK_getTag";
import { calls } from "../body/calls";
import { baseCalss } from "../../base/baseCalss";
import { Api_skillInfo_effect } from "../../../shared/master/body/skill/PtlLook";
import { Tpl_skillInfo } from "../../../shared/master/MsgAction";

interface EffectInput {
    read: string;
    val: number;
    type: string; // 添加其他计算类型的枚举值
    loca?: number;

    /**
     * 转化数值 与 等级数值连接符
     */
    leve_type: string
    /**
     * 具体数值 = leve_sup * leve
     */
    leve_sup: number
}
interface EffectData {
    /**
* 如果这个效果为buff,那么需要标记持续时间
*/
    time?: number;
    /**
     * 如果这个效果为召唤,那么需要填写召唤的怪物ID
     */
    create_id?: string
    input: EffectInput[];
    formula: string;
}
export interface Effect_item {
    rang: number;
    effect: EffectType;
    /**
     * 如果这个效果有概率触发则需要填写概率  百分制
     */
    dice?: number;
    data: EffectData;
    create: Function

}
export interface Effect extends Effect_item {
    tag: Effect_tag;
    condition: EffectCondition;
    effect_key: cfg_effectKey
}



export interface SK_data extends SK_data_db {
    effect: Effect[],
    minType?: Sk_minType,
    type: SK_type,
    name: string,
    desc: string,
    useUp: string
}

export interface SK_data_db {
    /**
     * 单位 秒
     */
    cd?: number;
    id?: string,
    rename?: string
    name: string
    data?: any
}


export interface battle_logNum extends battle_log {
    val: number
}
export interface battle_log {
    use_uuid: string,
    use_name: string,
    sk_name: string,
    group: group,
    type: EffectType,
    val: number | string
}

export class SKILL extends baseCalss {
    id: string = `skill_${app.v4()}`;
    data: any = {};
    effect!: Effect[];
    cd: number = 0;
    icon_img: string = '../../resources/img/skill/style/test.jpg'
    score: number = 0;
    leve: bar = {
        num: 1,
        now: 0,
        max: 100
    }
    exp_max: number = 100;
    exp_now: number = 0;
    rename: string = '待命名技能';
    name: string = '待命名技能';
    type: SK_type = SK_type.主动技能;
    minType: Sk_minType = Sk_minType.技能;
    useUp: string = '';
    _useUpDesc: string = ''
    useNumVaule: number = 0;
    /**
     * 技能归属名称
     */
    desc: string = '技能描述';
    _parent!: baseBody;
    /**
     * 技能上一个效果的目标人群
     */
    _lastFilteredBodys: baseBody[] = [];
    _lastActiveTime = 0;
    private _useUpCall!: Function;
    constructor(e: SK_data_db) {
        super();
        if (!e) {
            debugger;
            return;
        }
        this.rename = e.rename || e.name
        for (const key in e) {
            if (key.startsWith('_')) {
                continue;
            }
            this[key] = e[key];
        }
        this.init_useUpCall()
    }
    get_panel(tag?: baseBody): Tpl_skillInfo {
        let effectVal: Api_skillInfo_effect[] = [];
        let look = tag || this._parent;
        this.resetParent(look);
        if (look) {
            for (let i = 0; i < this.effect.length; i++) {
                const element = this.effect[i] as Effect;
                switch (element.effect) {
                    case EffectType.召唤永久单位:
                        const table = app.xlsxCfgMap.get(xlsxCfgNames.召唤表) as Map<string, any>;
                        const create_id = element.data.create_id as string;
                        effectVal.push({
                            EffectType: element.effect,
                            rang: element.rang,
                            create_name: table.get(create_id).name,
                            tag: element.tag,
                            val: 0,
                            EffectCondition: element.condition
                        })
                        break
                    case EffectType.恢复目标生命值:
                        effectVal.push({
                            EffectType: element.effect,
                            rang: element.rang,
                            tag: element.tag,
                            val: this._formula(element, look),
                            EffectCondition: element.condition
                        })
                        break;
                    case EffectType.永久增加最大生命值:
                    case EffectType.对目标造成物理伤害:
                    case EffectType.对目标造成魔法伤害:
                    case EffectType.真实伤害:
                    case EffectType.增加金币:
                    case EffectType.屏障:
                        effectVal.push({
                            EffectType: element.effect, rang: element.rang, tag: element.tag, val: this._formula(element, look),
                            EffectCondition: element.condition
                        })
                        break;
                    // buff类
                    case EffectType.buff_提升物理吸血:
                    case EffectType.buff_提升最大生命:
                    case EffectType.buff_提升生命恢复:
                    case EffectType.buff_提升最大魔法值:
                    case EffectType.buff_提升魔法值恢复速度:
                    case EffectType.buff_提升最大物攻:
                    case EffectType.buff_提升最小物攻:
                    case EffectType.buff_提升攻击速度:
                    case EffectType.buff_提升最大魔攻:
                    case EffectType.buff_提升最小魔攻:
                    case EffectType.buff_提升魔法防御:
                    case EffectType.buff_提升物理防御:
                    case EffectType.buff_提升魔法暴击率:
                    case EffectType.buff_提升物理暴击率:
                    case EffectType.buff_提升魔法吸血:
                        effectVal.push({
                            EffectType: element.effect, rang: element.rang, tag: element.tag, val: this._formula(element, look), time: element.data.time,
                            EffectCondition: element.condition
                        })
                        break;
                    default:
                        // effectVal.push('错误')
                        break;
                }
            }
        }

        let obj: Tpl_skillInfo = {
            cd: this.cd,
            type: this.type,
            show: this.icon_img,
            minType: this.minType,
            desc: this.desc,
            /**
             * 效果具体数值
             */
            effectVal: effectVal,
            name: this.rename,
            useUp: this._useUpDesc,
            score: this.score,
            leve: this.leve,
        }
        return obj
    }
    private init_useUpCall() {
        if (this.useUp.length == 0) {
            this._useUpDesc = '无消耗';
            this._useUpCall = this.tool_useUp_none;
            return;
        }
        const useArry = this.useUp.split('-')
        const useVauleType = useArry[0];//消耗类型
        const useNumType = useArry[1];//消耗方式
        const useNumVaule = Number(useArry[2]);//消耗数值
        this.useNumVaule = useNumVaule;

        switch (useVauleType) {
            case 'mp':
                if (useNumType == '/') {
                    this._useUpDesc = `MP${useNumVaule}点`
                    this._useUpCall = this.tool_useUp_fixmp;
                } else if (useNumType == '%') {
                    this._useUpDesc = `最大MP百分之${useNumVaule}%`
                    this._useUpCall = this.tool_useUp_rangMp;
                }
                break;

            default:
                break;
        }

    }
    /**
     * 增加技能经验
     * @param n 
     */
    addExp(n: number) {
        app.leveAddExp(n, this.leve, this.upLeve);
    }
    private upLeve = () => {
        this.leve.num += 1;
        this.leve.max = this.leve.num * 1000 + app.random(this.leve.num * this.score * 3, this.leve.num * this.score * 4);
    }
    // 消耗固定魔法值
    private tool_useUp_fixmp(read?: boolean) {
        if (this.useNumVaule > this._parent.Mp_now) {
            return false;
        }
        if (read) {
            this._parent.tool_changeMp({
                use_uuid: "-1",
                use_name: "自己",
                sk_name: "技能消耗",
                group: group.主场,
                type: EffectType.none,
                val: this.useNumVaule
            })
        }
        return true;
    }
    //消耗百分百魔法值
    private tool_useUp_rangMp(read?: boolean) {
        return true;
    }

    private tool_useUp_none(read?: boolean) {
        return true;
    }
    checkUseUp(read?: boolean) {
        return this._useUpCall(read)
    }

    resetParent(tag: baseBody) {
        this._parent = tag;
    }
    getCdTime() {
        if (this.checkUseCd()) {
            return 0
        } else {
            let endTime = ((this._lastActiveTime + this.cd * 1000 - Date.now()) / 1000);
            return Number(endTime.toFixed(1))
        }
    }
    checkUseCd() {
        if (this._lastActiveTime + this.cd * 1000 < Date.now()) {
            return true;
        }
        else {
            return false;
        }
    }
    /**
     * 主动释放技能
     * @param bodys 
     */
    use(bodys: baseBody[], eff?: Effect) {
        if (!this.checkUseCd()) {
            return;
        }
        app.shuffleArray(bodys);
        this._lastActiveTime = Date.now();
        // 分析目标
        let forApplyCont = 1;
        if (this.minType == Sk_minType.普通攻击) {
            forApplyCont = Math.ceil(this._parent._attributes.Attack_Speed) || 1;
        }

        let effList = eff ? [eff] : this.effect as Effect[];

        for (let effect of effList) {
            let tag_rang: baseBody[] = SK_getTag.count(this, effect.tag, bodys);
            // 过滤出符合技能释放条件的单位组
            let tag_filter = tag_rang.filter((e) => {
                return this.checkCondition(effect, e)
            });
            if (!tag_filter.length) {
                return;
            }
            let rang = effect.rang > tag_filter.length ? tag_filter.length : effect.rang;
            if (rang > 0) {
                this._lastFilteredBodys = [];
            }
            for (let j = 0; j < forApplyCont; j++) {
                for (let index = 0; index < rang; index++) {
                    const tag_item = tag_filter[index];
                    let check = this.checkCondition(effect, tag_item)
                    if (!check) {
                        continue;
                    }
                    this._lastFilteredBodys.push(tag_item);
                    SK_applyEffect.count(this, effect, tag_item)
                }
            }

        }
        if (this.minType == Sk_minType.普通攻击) {
            this._parent.sk_trigger(EffectCondition.auto_普通攻击时, bodys);
        }
    }
    /**
     * 自动释放技能
     * @param trigger 
     * @param bodys 
     */
    autoUse(trigger: EffectCondition, bodys: baseBody[]) {
        if (!this.checkUseCd()) {
            return;
        }
        for (let effect of this.effect) {
            if (trigger != effect.condition) {
                continue;
            }
            this.use(bodys, effect)
        }
    }
    /**
     * 检测概率判定结果
     * @param eff 
     * @returns 
     */
    private checkRollDice(eff: Effect) {
        if (typeof (eff.dice) != 'number') {
            return true;
        }
        let multiplier = 1;
        if (!Number.isInteger(eff.dice)) {
            multiplier = Math.pow(10, eff.dice.toString().split(".")[1].length);
        }
        return app.random(0, 100 * multiplier) >= eff.dice * multiplier; // 如果有小数点，则乘以合适的倍数放大
    }

    // 检查技能条件是否满足
    private checkCondition(eff: Effect, tag: baseBody) {
        let diceJude = this.checkRollDice(eff)
        if (!diceJude) {
            return false;
        }
        switch (eff.condition) {
            case EffectCondition.无:
                return true;
            case EffectCondition.目标生命值高于百分之70:
                return (tag.Hp_now / tag._attributes.Hp_Max) > 0.7;
            default:
                return true
        }
    }
    tool_getLogInfo(tag: baseBody) {
        let uuid = this._parent.uuid;
        let sk_id = this.id;
        if (this._parent instanceof calls) {
            // uuid = `c-s-${this._parent.name}`
            sk_id = `c-s-${this.name}`
        }

        return {
            sk_id: sk_id,
            sk_name: this.rename,
            use_name: this._parent.nickName,
            use_uuid: uuid,
            group: this._parent.get_group()
        }
    }
    tool_getTagGroup(tag: baseBody) {
        try {
            return tag.get_group()
        } catch (error) {
            debugger
        }
    }
    tool_getGroup() {
        try {
            return this._parent.get_group()
        } catch (error) {
            debugger
        }
    }
    /**
     * 根据字符出给出运算结果
     * @param a 
     * @param b 
     * @param type 
     * @returns 
     */
    private symbolics(a: number, b: number, type: string) {
        let val = 0;
        switch (type) {
            case '%':
                val = a / b;
                break;
            case '+':
                val = a + b;
                break;
            case '*':
                val = a * b;
                break;
            default:
                logger.error('没有匹配到计算字符');
                debugger;
                break;
            // 添加其他计算类型的逻辑
        }
        return val;
    }
    _formula(eff: Effect, tag: baseBody) {
        for (let input of eff.data.input) {
            const value = eval(
                input.read.replace(/me/g, 'this._parent')
            ) || 0;
            const type = input.type;
            input.loca = 0;

            input.loca = this.symbolics(value, input.val, type);
            input.loca = this.symbolics(input.loca, this.leve.num * input.leve_sup, input.leve_type);
        }

        const formula = eff.data.formula;
        const formulaFunction = new Function('T', 'return ' + formula.replace(/(\d)/g, function (match) {
            return String(eff.data.input[parseInt(match)].loca);
        }));
        let result = formulaFunction(0);
        return result;
    }
    destroy(): void {
        if (this._parent) {
            this._parent.del_buff(this.id);
        }
        super.destroy();
    }
}